<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>AutoHotkey Scripts and Macros</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="alternate" type="application/rss+xml" title="AutoHotkey Forum RSS" href="../forum/rss.php">
<link href="css/default.css" rel="stylesheet" type="text/css">
</head>
<body>

<h1>脚本</h1>

<h2>目录</h2>
<ul>
  <li><a href="#intro">简介</a></li>
  <li><a href="#auto">脚本顶部 (自动执行段</a>): 当脚本启动时, 这部分会自动执行.</li>
  <li><a href="#esc">转义序列</a>: 什么时候应该使用 `% 和 `, 表示一个原义的百分号和逗号.</li>
  <li><a href="#Comments">脚本中的注释</a>: 使用分号和 /*...*/ 给脚本添加注释. </li>
  <li><a href="#continuation">把一个过长的行分割成一系列短行</a>: 这样可以提高脚本的可读性和可维护性.</li>
  <li><a href="#ahk2exe">把脚本转换成 EXE 文件 (ahk2exe)</a>: 把 .ahk 脚本转换成可以在任何 PC 上运行的 .exe 文件.</li>
  <li><a href="#cmd">向脚本传递命令行参数</a>: %1%, %2% 等变量包含了传入的参数.</li>
  <li><a href="#cp">脚本文件代码页</a>: 在脚本中可靠地使用非 ASCII 字符.</li>
  <li><a href="#debug">调试脚本</a>: 如何找出无法正常工作脚本中的问题.</li>
  <li><a href="#port">AutoHotkey.exe 的可移植性</a>: 有一个 AutoHotkey.exe 的副本足以执行任何的 .ahk 文件.</li>
  <li><a href="#install">安装程序选项</a>: 如何无人值守/静默的安装或卸载.</li>
</ul>
<h2 id="intro">简介</h2>
<p>每个脚本都是一个纯文本文件, 其中包含了可由程序 (AutoHotkey.exe) 执行的文本行. 脚本中还可以包含 <a href="Hotkeys.htm">热键</a> 和 <a href="Hotstrings.htm">热字串</a>, 或者甚至完全由它们组成. 不过, 在不存在热键和热字串时, 脚本会在启动后从上往下按顺序执行其中的命令.</p>
<p>程序会把脚本逐行加载到内存中, 每行最多可以包含 16,383 个字符. 在加载过程中, 脚本将被 <a href="misc/Performance.htm">优化</a> 和验证. 任何语法错误都会被列出, 纠正它们后脚本才能运行.</p>
<h2><a name="auto" id="auto"></a>脚本顶部 (自动执行段)</h2>
<p> 脚本加载完成后, 它会从顶行开始执行, 直到遇到 <a href="commands/Return.htm">Return</a>, <a href="commands/Exit.htm">Exit</a>,<a href="Hotkeys.htm">热键/热字串标签</a> 或脚本的底部 (无论最先遇到哪个). 脚本的这个顶端部分被称为 <em>自动执行</em> 段.</p>
<p>如果一个脚本不是 <a href="commands/_Persistent.htm">持续运行的</a> 并且不含有 <a href="Hotkeys.htm">热键</a>, <a href="Hotstrings.htm">热字串</a>, <a href="commands/OnMessage.htm">OnMessage</a> 和 <a href="commands/Gui.htm">GUI</a>, 那么它会在自动执行段结束后终止. 否则, 它会以空闲状态继续运行, 从而对例如热键, 热字串, <a href="commands/Gui.htm#label">GUI 事件</a>, <a href="commands/Menu.htm">自定义菜单项</a> 和 <a href="commands/SetTimer.htm">计时器</a> 这些事件进行响应.</p>
<p>每个由 <a href="Hotkeys.htm">热键</a>, <a href="Hotstrings.htm">热字串</a>, <a href="commands/Menu.htm">菜单项</a>, <a href="commands/Gui.htm#label">GUI 事件</a> 或 <a href="commands/SetTimer.htm">计时器</a> 启动的 <a href="misc/Threads.htm">线程</a> 都以在自动执行段设置的下列属性值作为默认值开始. 如果未设置, 则使用标准的默认值 (与下面每个页面中注明的一样): <a href="commands/DetectHiddenWindows.htm">DetectHiddenWindows</a>, <a href="commands/DetectHiddenText.htm">DetectHiddenText</a>, <a href="commands/SetTitleMatchMode.htm">SetTitleMatchMode</a>, <a href="commands/SetBatchLines.htm">SetBatchLines</a>, <a href="commands/SendMode.htm">SendMode, </a><a href="commands/SetKeyDelay.htm">SetKeyDelay</a>, <a href="commands/SetMouseDelay.htm">SetMouseDelay</a>, <a href="commands/SetWinDelay.htm"></a><a href="commands/SetWinDelay.htm">SetWinDelay</a>, <a href="commands/SetControlDelay.htm">SetControlDelay</a>, <a href="commands/SetDefaultMouseSpeed.htm">SetDefaultMouseSpeed</a>, <a href="commands/CoordMode.htm">CoordMode</a>, <a href="commands/SetStoreCapslockMode.htm">SetStoreCapslockMode</a>,
<a href="commands/AutoTrim.htm">AutoTrim, </a><a href="commands/SetFormat.htm">SetFormat</a>, <a href="commands/StringCaseSense.htm">StringCaseSense</a>, <a href="commands/Thread.htm">Thread</a> 和 <a href="commands/Critical.htm">Critical</a>.</p>
<p>如果自动执行段花了很长时间才结束 (或从未结束), 上面这些设置的默认值将在 100 毫秒后自动生效. 当自动执行段最终结束 (如果可能) 时, 在自动执行段末尾生效的那些设置才更新为默认值. 因此, 通常最好在包含 <a href="/docs/Hotkeys.htm">热键</a>, <a href="Hotstrings.htm">热字串</a>, <a href="/docs/commands/SetTimer.htm">计时器</a> 或 <a href="commands/Menu.htm">自定义菜单项</a> 的脚本顶部设置自己想要的默认值. 还要注意, 每个 <a href="misc/Threads.htm">线程</a> 会保存它自己的上述这些设置的一个集合. 在一个线程中对这些设置的的改变不会影响其他 <a href="misc/Threads.htm">线程</a>.</p>
<h2 id="esc">转义序列</h2>
<p>AutoHotkey 中默认的 <a href="commands/_EscapeChar.htm">转义符</a> 为重音符/反引号 (`), 它位于大多数英文键盘的左上角. 使用这个字符而不是反斜线可以避免在文件路径中使用双反斜线.</p>
<p>由于在 AutoHotkey 语言中逗号和百分号具有特殊含义, 因此需要使用 `, 来指定一个原义的逗号, 使用 `% 指定一个原义的百分号. 其中的一个例外 <a href="commands/MsgBox.htm">MsgBox</a>, 它里面不需要将逗号进行转义. 另一个例外是在任意命令最后一个参数中的逗号: 它们不需要进行转义. 参见 <a href="commands/_EscapeChar.htm">#EscapeChar</a> 了解转义序列的完整列表.</p>
<p>某些特殊的字符也需要使用转义序列的方法生成. 最常见的有 `t (tab), `n (换行) 和 `r (回车).</p>
<p>提示: 任意命令中的首个逗号可以省略 (除非首个参数为空或以 := 或 = 开始, 或命令单独处于 <a href="#continuation">字串分段</a> 的顶部). 例如:</p>
<pre>MsgBox This is ok.
MsgBox<strong>,</strong> This is ok too (it has an explicit comma).</pre>
<h2 id="Comments">脚本中的注释 </h2>
<p>在行首使用分号可以注释脚本. 例如:</p>
<pre><em>; This entire line is a comment.</em></pre>
<p>也可以在命令的末尾添加注释, 此时分号左侧必须至少有一个空格或 tab. 例如:</p>
<pre>Run Notepad  <em>; This is a comment on the same line as a command.</em></pre>
<p>此外, 使用 /* 和 */ 符号可以注释整块, <em>但仅当它们出现在行首时才有效</em>, 例如:</p>
<pre class="CodeCom">/*
MsgBox, This line is commented out (disabled).
MsgBox, This one too. 
*/</pre>
<p>由于脚本运行时会忽略注释, 所以它们不会影响脚本性能或占用内存.</p>
<p>使用 <a href="commands/_CommentFlag.htm">#CommentFlag</a> 可以把默认注释符 (分号) 更改为其他字符或字符串.</p>
<h2 id="continuation">把一个过长的行分割成一系列短行</h2>
<p>过长的行可以分割成一系列较短的行来提高可读性和可维护性. 这样不会降低脚本的执行速度, 因为在脚本启动时这些短行会在内存中合并起来.</p>
<p><strong>方法 #1</strong>: 以 "and", "or", ||, &amp;&amp;, 逗号 或 <a href="Variables.htm#concat">句点</a> 开头的行会自动合并到其 (在 1.0.46+ 版本中, 以除了 ++ 和 -- 外所有其他的 <a href="Variables.htm#Operators">表达式运算符</a> 开头的行也会如此). 在下面的例子中, 第二行会自动附加到首行, 因为它以逗号开头:</p>
<pre>FileAppend, This is the text to append.`n   <em>; 这里可以使用注释.</em>
    <strong>,</strong> %A_ProgramFiles%\SomeApplication\LogFile.txt  <em>; 注释.</em></pre>
<p>类似地, 下列几行会合并成单行, 因为最后两行以 "and" 或 "or" 开始:</p>
<pre>if (Color = "Red" or Color = "Green"  or Color = "Blue"   <em>; 注释.</em>
    <strong>or</strong> Color = "Black" or Color = "Gray" or Color = "White")   <em>; 注释.</em>
    <strong>and</strong> ProductIsAvailableInColor(Product, Color)   <em>; 注释.</em></pre>
<p><a href="Variables.htm#ternary">三元运算符</a> 也是个不错的候选:</p>
<pre>ProductIsAvailable := (Color = "Red")
    <strong>?</strong> false  <em>; 我们没有任何红色产品, 所以不用那么麻烦去调用函数.</em>
    <strong>:</strong> ProductIsAvailableInColor(Product, Color)</pre>
<p>尽管在上面的例子中缩进不是必须的, 但它可以指出哪些行属于上一行从而提高代码的清晰度. 并且可以不必在以单词 "AND" 和 "OR" 开始的行的开头加上额外的空格; 程序会自动处理这些. 最后, 可以在上面例子中任意行的末尾或行与行之间添加空行或 <a href="#Comments">注释</a>.</p>
<p> <strong>方法 #2</strong>: 这种方法可以合并大量的行或者方法 #1 不适合处理的行. 尽管此方法对 <a href="Hotstrings.htm">自动替换热字串</a> 特别有用, 但它也可以用于任意命令或 <a href="Variables.htm#Expressions">表达式</a>. 例如:</p>
<pre><em>; 示例 #1:</em>
Var =
(
Line 1 of the text.
Line 2 of the text. By default, a linefeed (`n) is present between lines.
)

<em>; 示例 #2:</em>
FileAppend<strong>,</strong>  <em>; The comma is required in this case.</em>
(
A line of text.
<i>By default</i>, the hard carriage return (Enter) between the previous line and this one will be written to the file as a linefeed (`n).
    <i>By default</i>, the tab to the left of this line will also be written to the file (the same is true for spaces).
<i>By default</i>, variable references such as %Var% are resolved to the variable's contents.
), C:\My File.txt</pre>
<p>在上面的例子中, 一系列行被头尾的一对括号包围起来. 这被称为 <em>字串分段</em>. 注意在底行的闭括号后面包含了 <a href="commands/FileAppend.htm">FileAppend</a> 的最后一个参数. 这个习惯是可选的; 这样做是为了在这种情况下把逗号视为参数分隔符而不是原义的逗号.</p>
<p>通过在开括号的右侧包含一个或多个下列选项, 可以覆盖字串分段的默认特性. 如果含有多个选项, 选项之间使用空格分隔. 例如: ( LTrim Join| %</p>
<p><strong><a name="Join"></a>Join</strong>: 指定行与行之间应该如何连接. 如果省略此选项, 除最后一行外的其他行后面都会跟一个换行符 (`n). 如果仅指定单词 <em>Join</em> 自身, 则行与行之间直接连接而不添加任何字符. 或者在单词 <em>Join</em> 后可以跟着多达 15 个字符. 例如, Join`s 会在除最后一行外的每行末尾插入一个空格 (<strong>`s</strong> 表示一个原义的空格 -- 这是个只能被 <em>Join</em> 识别的特殊转义序列). 另一个例子是 <em>Join`r`n</em>, 它会在行与行之间插入 CR+LF. 同样地, <em>Join|</em> 会在行之间插入管道符. 要让字串分段部分的最后一行也以连接字符串结尾, 需要在闭括号上一行添加一个空行.</p>
<p><strong><a name="LTrim"></a>LTrim</strong>: 删除每行开头的空格和 tab. 主要用来允许字串分段使用缩进. 此外, 通过在一行中指定 <em>#LTrim</em> 自身可以为多个字串分段打开此选项. <em>#LTrim</em> 是可选的: 它会影响它下面的所有字串分段. 通过 <em>#LTrim Off</em> 可以关闭此设置.</p>
<p><strong>RTrim0</strong> (RTrim 后面跟着一个零): 关闭自动删除每行末尾的空格和 tab 的设置.</p>
<p><strong><a name="CommentOption"></a>Comments</strong> (或 <strong>Comment</strong> 或 <strong>Com</strong> 或 <strong>C</strong>) <span class="ver">[v1.0.45.03+]:</span> 允许在字串分段中使用 <a href="#Comments">分号注释</a> (但不支持 /*..*/). 这样的注释 (以及它们左边的任何空格和 tab) 在连接时完全被忽略而不是当成原义文本处理. 每个注释可以放在一行的右侧或单独一行中.</p>
<p><strong>%</strong> (百分号): 把百分号作为原义字符而不是变量引用. 这样就可以不需要对每个百分号 <a href="commands/_EscapeChar.htm">转义</a> 成原义字符. 在百分号已经为原义的地方就不需要此选项了, 例如 <a href="Hotstrings.htm">自动替换热字串</a>.</p>
<p><strong>,</strong> (逗号): 把逗号作为分隔符而不是原义逗号. 这个非常少用的选项只有在命令参数之间才会用到, 因为在 <a href="Functions.htm">函数调用</a> 中, 逗号的类型没有影响. 并且, 此选项只会转换那些真正分隔参数的逗号. 换句话说, 一旦到达命令的最后一个参数 (或者命令没有参数), 会忽略此选项而把后续的逗号当成原义的逗号.</p>
<p><a name="accent"></a><strong>`</strong> (重音符): 把每个反引号作为原义字符而不是 <a href="commands/_EscapeChar.htm">转义符</a>. 此选项同时也避免了需要分别对逗号和百分号进行明确地转义. 此外, 它还阻止对任何特定的转义序列例如 `r 和 `t 进行转换.</p>
<p><u>备注</u></p>
<p>未指定 <a href="#accent">重音符 (`) 选项</a> 时, 在字串分段内支持使用 <a href="commands/_EscapeChar.htm">转义序列</a> 例如 `n (换行符) 和 `t (tab).</p>
<p>未指定 <a href="#CommentOption">comment 选项</a> 时, 在字串分段内不支持使用分号和 /*..*/ 注释, 此时它们会被视为原义的文本. 但是, 可以在字串分段的顶部和底部行添加注释. 例如:</p>
<pre>FileAppend<strong>,</strong>   <em>; 注释.
; Comment.</em>
( LTrim Join    <em>; 注释.</em>
    &nbsp;; 此行 <strong>不是</strong> 注释; 它是原义的. 在上一行使用单词 <i>Comments</i> 可以让这行成为注释.
), C:\File.txt   <em>; 注释.</em></pre>
<p>根据上面可以得出结论, 在字串分段中的分号不需要进行 <a href="commands/_EscapeChar.htm">转义</a>.</p>
<p>使用字串分段的方法无法生成总长度大于 16,383 字符的行 (如果尝试这样做, 那么程序在启动时将弹出警告). 一种变通的解决方法是把一系列内容连接到一个变量中. 例如:</p>
<pre>Var =
(
...
)
Var = %Var%`n  <em>; 通过另一个字串分段添加更多的文本到此变量中.</em>
(
...
)
FileAppend, %Var%, C:\My File.txt</pre>
<p> 因为闭括号表示字串分段的结束, 要让某一行以原义的闭括号开头, 需要在其前面加上一个重音符/反引号: `).</p>
<p>一个字串分段后面可以立即跟着包含另一个字串分段的开括号的一行. 这样使得上面提到的选项可以在创建单行的过程中进行改变.</p>
<p>不支持通过 <a href="commands/_Include.htm">#Include</a> 的方法把字串分段各部分连接起来.</p>
<h2 id="ahk2exe">把脚本转换成 EXE 文件 (ahk2exe)</h2>
<p>在程序中包含了一个脚本编译器 (承蒙 Jonathan Bennett 提供的 AutoIt v3 源码). 不支持 AutoIt v2 脚本, 所以如果需要, 首先把你的 .aut 文件 <a href="AutoIt2Users.htm#convert">自动转换为</a> .ahk.</p>
<p> 当脚本编译完成后, 就成为了一个独立的可执行文件; 即它甚至可以在没有安装 AutoHotkey 的机器上运行 (并且这样的 EXE 文件可以随意发布或出售). 在编译过程中会对下列所有文件进行压缩和加密: 脚本, 脚本所 <a href="commands/_Include.htm">include</a> 的任何文件, 以及通过 <a href="commands/FileInstall.htm">FileInstall</a> 合并的任何文件.</p>
<p>编译不会提高脚本的性能. 实际上, 已编译脚本在启动时会稍慢, 因为首先必须把它解密和解压缩到内存中, 然后才像普通脚本那样进行 <a href="misc/Performance.htm">优化</a>.</p>
<p>使用 Ahk2Exe 有下列几种方式:</p>
<ol>
  <li><strong>图形界面</strong>: 运行开始菜单中的 "Convert .ahk to .exe" 菜单项.</li>
  <li><strong>右键点击</strong>: 在资源管理器窗口中, 你可以右键点击任一 .ahk 文件并选择 "Compile Script" (只有在安装 AutoHotkey 时选择脚本编译器选项才可用). 这样就创建了与原来的脚本具有相同的主文件名的 EXE 文件, 它在稍后出现在同一个的目录中. 注意: 这样会用和方法 #1 中最后一次使用的自定义图标和压缩等级相同的设置来生成 EXE 文件, <u>并且没有设置密码</u>.</li>
  <li><a name="ahk2exeCmd"></a><strong>命令行</strong>: 编译器可以使用下列参数在命令行中运行: <pre>Ahk2exe.exe /in MyScript.ahk [/out MyScript.exe] [/icon MyIcon.ico] [/pass password] [/bin AutoHotkeySC.bin]</pre>
  例如:
<pre>Ahk2exe.exe /in "MyScript.ahk" /icon "MyIcon.ico" /pass "CustomPassword"</pre>
用法:
<ul>
<li>含有空格的参数应该包围在双引号中.</li>
<li>如果省略了 "out" 文件, 则使用脚本文件的主名作为 EXE 文件主名.</li>
</ul></li>
</ol>
<p>请注意:</p>
<ul>
  <li>含有非 ASCII 字符的脚本文件 <u>必须使用 UTF-8 编码</u>. 但是, 因为 Ahk2Exe 不支持 Unicode 文件名, 所以在 #Include 和 FileInstall 文件名中只能使用 ASCII 字符.</li>
  <li>如果你打算发布自己的 EXE 文件并且不想让任何人看到脚本的源码, 考虑使用非标准的 <a href="http://en.wikipedia.org/wiki/Executable_compression">可执行文件打包器</a>. MPRESS, AutoHotkey_L 默认使用的打包器, 可以为大多数用户提供足够的保护. 仅在 32 位编译时支持密码保护, 并且不再支持 /NoDecompile 开关.</li>
  <li><a href="commands/_NoTrayIcon.htm">#NoTrayIcon</a> 和 "<a href="commands/Menu.htm">Menu, Tray, ShowMainWindow</a>" 命令会影响已编译脚本的行为.</li>
  <li><a name="exe2ahk"></a>下载 <a href="http://www.autohotkey.com/download/Exe2Ahk.exe">Exe2Ahk</a> (此工具应该在命令提示符中运行) 执行可以反编译 32 位的 EXE 文件来获取它的原始脚本. 对于 64 位的 EXE 文件, 可以使用像 Resource Hacker 这样的资源编辑器提取原始脚本, 可以得到没有使用 MPRESS 或类似工具压缩过的 EXE 文件 (是指脱壳的意思吧). 不过, 原来的所有 <a href="#comments">注释</a> (分号或 /**/) 都会丢失.</li>
  <li>使用像 Resource Hacker (免费软件) 这样的工具编辑 "AutoHotkeySC.bin" 文件, 可以把自定义的版本信息 (在资源管理器的文件属性对话框中看到的那些) 添加到你的已编译脚本中. 这个文件包含了 AutoHotkey 安装目录的 "compiler" 子文件夹中. 注意: Resource Hacker 会破坏已编译脚本, 这是为什么只应该编辑 AutoHotkeySC.bin 文件的原因. <a href="http://www.autohotkey.com/forum/topic22975.html">Compile_AHK II</a> 可以用来简化编译的过程.</li>
  <li>上面的方法还可以用来改变所有已编译脚本中现有的图标或添加新的图标.</li>
  <li>如果脚本以已编译的形式运行, 则内置变量 A_IsCompiled 的值为 1. 否则为空.</li>
  <li>如果你不希望对已编译的脚本进行压缩, 删除或重命名 AutoHotkey 的 "Compiler" 文件夹中的  "mpress.exe" (或较旧版本中为 "upx.exe") 文件.</li>
  <li>当参数传递给 Ahk2Exe 执行时, 会在标准输出中写入一条表示编译成功与否的消息. 尽管此消息不会显示在命令提示符中, 但可以通过像重定向到文件的方法 "捕获". <span class="ver">[v1.0.43+]</span></li>
</ul>

<h2 id="cmd">向脚本传递命令行参数</h2>
<p>脚本支持命令行参数. 格式为:</p>
<pre>AutoHotkey.exe [<i>Switches</i>] [<i>Script Filename</i>] [<i>Script Parameters</i>]</pre>
<p>对于已编译脚本, 格式为:</p>
<pre>CompiledScript.exe [<i>Switches</i>] [<i>Script Parameters</i>]</pre>
<p><strong>Switches:</strong> 零个或多个下列开关: <br>
/f 或 /force -- 无条件运行, 跳过任何警告对话框. <br>
/r 或 /restart -- 提示脚本应该重新加载 (在脚本内部可以使用 <a href="commands/Reload.htm">Reload</a> 命令).<br>
/ErrorStdOut -- 把阻止脚本运行的语法错误发送到标准输出而不是显示在对话框中. 参见 <a href="commands/_ErrorStdOut.htm">#ErrorStdOut</a> 了解详情.<br>
/Debug -- <span class="ver">[AHK_L 11+]:</span> 连接到调试客户端. 更多详情参见 <a href="#idebug">交互调试</a>.<br>
<a name="CPn"></a>/CP<i>n</i> -- <span class="ver">[AHK_L 51+]:</span> 覆盖用来读取脚本文件的默认代码页. 更多详情参见 <a href="#cp">脚本文件代码页</a>.</p>
<p><a name="defaultfile"></a><strong>Script Filename:</strong> 如果没有 <em>Script Parameters</em>, 那么此参数可以省略. 如果省略, 它将会运行 (或者提示你创建) 下列默认位置的其中一个文件:</p>
<p><span class="ver">[AHK_L 51+]:</span> <code>%AhkExeDir%\%AhkExeName%.ahk</code> 或 <code><a href="Variables.htm#MyDocuments">%A_MyDocuments%</a>\%AhkExeName%.ahk</code>, 此处 <em>%AhkExeDir%</em> 和 <em>%AhkExeName%</em> 需要使用运行当前脚本的可执行文件的目录和文件名替换, 不包括 ".exe" 扩展名.</p>
<p><span class="ver">[早期版本]:</span> <code>AutoHotkey.ini</code> (在当前工作目录) 或 <code><a href="Variables.htm#MyDocuments">%A_MyDocuments%</a>\AutoHotkey.ahk</code>.</p>
<p><strong>Script Parameters:</strong> 你想要传递给脚本的字符串, 字符串之间使用空格分隔. 任何含有空格的参数应该包围在一对双引号之间. 要传递一个原义的引号, 在其前面加上一个反斜线 (\"). 因此, 任何引号包围的参数 (例如 "C:\My Documents<span class="red">\"</span>) 中末尾的反斜线会让紧跟着的引号被当作原义的引号进行处理 (即脚本将会接收到字符串 C:\My Documents<span class="red">"</span>). 要移除这样的引号, 使用 <em><a href="commands/StringReplace.htm">StringReplace, 1, 1, <span class="red">"</span>,, All</a></em></p>
<p>脚本中把传入的参数视为 <a href="Variables.htm">变量</a> %1%, %2% 等等. 此外, 变量 %0% 包含了传入参数的数目 (没有则为 0). 在下面的例子中, 如果传入的参数过少脚本会退出:</p>
<pre>if 0 &lt; 3  <em>; <a href="commands/IfEqual.htm">非表达式 if 语句</a> 左侧总是变量名.</em>
{
    MsgBox This script requires at least 3 incoming parameters but it only received %0%.
    ExitApp
}</pre>
<p>如果传递给脚本的参数数目不确定 (可能由于用户拖放一组文件到脚本上), 可以使用下面的例子逐个提取它们:</p>
<pre>Loop, %0%  <em>; For each parameter:</em>
{
    param := %A_Index%  <em>; 取得名称为 A_Index 的值的变量中的内容.</em>
    MsgBox, 4,, Parameter number %A_Index% is %param%.  Continue?
    IfMsgBox, No
        break
}</pre>
<p>如果这些参数是文件名, 可以使用下列的例子把它们转换到大小写正确的长文件名 (与文件系统中储存的一致), 包含完整/绝对的路径:</p>
<pre>Loop %0%  <em>; For each parameter (or file dropped onto a script):</em>
{
    GivenPath := %A_Index%  <em>; 取得名称为 A_Index 的值的变量中的内容.</em>
    Loop %GivenPath%, 1
        LongPath = %A_LoopFileLongPath%
    MsgBox The case-corrected long path name of file`n%GivenPath%`nis:`n%LongPath%
}</pre>
<p>已知限制: 如果 NTFS 文件系统中关闭了 8.3 (短) 文件名, 拖拉文件到 .ahk 脚本上可能无法正常工作. 一个变通的解决方法是 <a href="#ahk2exe">编译</a> 脚本, 然后拖放文件到产生的 EXE 文件上.</p>

<h2 id="cp">脚本文件代码页 <span class="ver">[AHK_L 51+]</span></h2>
<p>脚本文件中可以使用的字符受到用来加载脚本的代码页的限制.</p>
<ul>
  <li>需要编译脚本的源文件 <b class="red">必须</b> 使用 <b>UTF-8</b> 编码或者仅使用 ASCII 字符.</li>
  <li>如果文件以 UTF-8 或 UTF-16 (LE) 字节顺序标记开头, 则会为其使用适合的代码页并且忽略 <a href="#CPn">/CP<i>n</i></a> 开关.</li>
  <li>如果在命令行中传递了 <a href="#CPn">/CP<i>n</i></a> 开关, 则使用代码页 <i>n</i>. 想了解有效的数值代码页标识符, 参见 <a href="http://msdn.microsoft.com/en-us/library/dd317756.aspx">MSDN</a>.</li>
  <li>其他所有情况下, Unicode 版本使用 UTF-8 而 ANSI 使用系统默认的 ANSI 代码页.</li>
</ul>
<p>由于所有的文本都被转换 (必要时) 为 <a href="Compat.htm#Format">原生的字符串格式</a>, 无效的或不存在于原生代码页中的字符都被替换为占位符: ANSI '?' 或 Unicode '�'. 在 Unicode 版本中, 这样的情况只可能在脚本文件编码错误或用于保存和读取脚本的代码页不一致时发生.</p>
<p><b class="red">请注意:</b><br>
在 Unicode 版本中, 如果指定的代码页不正确, 则非 ASCII 字符很可能被曲解或替换为 �. 推荐使用 UTF-8 编码. 如果你的首选编辑器不支持 UTF-8 (或带 BOM 的 UTF-16), 使用 <a href="#CPn">/CP<i>n</i></a> 开关 - 把 <i>n</i> 替换为 0 或者你系统 ANSI 代码页的数值标识符.</p>
<p>可以使用 <a href="commands/RegWrite.htm">RegWrite</a> 为资源管理器中运行的脚本设置默认代码页 (例如双击脚本文件时):</p>
<pre><em>; Uncomment the appropriate line below or leave them all commented to
;   reset to the default of the current build.  Modify as necessary:
; codepage = 0        ; System default ANSI codepage
; codepage = 65001    ; UTF-8
; codepage = 1200     ; UTF-16
; codepage = 1252     ; ANSI Latin 1; Western European (Windows)</em>
if (codepage != "")
    codepage := " /CP" . codepage
cmd="%A_AhkPath%"%codepage% "`%1" `%*
key=AutoHotkeyScript\Shell\Open\Command
if A_IsAdmin    <em>; Set for all users.</em>
    RegWrite, REG_SZ, HKCR, %key%,, %cmd%
else            <em>; Set for current user only.</em>
    RegWrite, REG_SZ, HKCU, Software\Classes\%key%,, %cmd%
</pre><p>使用这个脚本前假定已经安装了 AutoHotkey_L. 如果没有安装结果可能不够理想.</p>

<h2 id="debug">调试脚本</h2>
<p><a href="commands/ListVars.htm">ListVars</a> 和 <a href="commands/Pause.htm">Pause</a> 等命令可以帮助你调试脚本. 例如, 把下面这两行临时插入精心选择的位置时, 可以在脚本中创建 "断点":</p>
<pre>ListVars<br>Pause</pre>
<p>当脚本执行到这两行时, 将会显示所有变量当前包含的内容供你检查. 当你准备恢复时, 可以通过 File 或 Tray 菜单取消暂停. 然后脚本会继续执行直到遇到下一个 "断点" (如果有的话).</p>
<p>通常最好把这些 "断点" 插入到活动窗口对当前脚本没什么影响的位置, 例如在 WinActivate 命令的前一行. 这样当你取消暂停时脚本才可以正确地恢复操作.</p>
<p>下列命令对调试也很有用: <a href="commands/ListLines.htm">ListLines</a>, <a href="commands/KeyHistory.htm">KeyHistory</a> 和 <a href="commands/OutputDebug.htm">OutputDebug</a>.</p>
<h3 id="idebug">交互调试 <span class="ver">[AHK_L 11+]</span></h3>
<p>通过受支持的 <a href="AHKL_DBGPClients.htm">DBGp 客户端</a> 可以进行交互调试. 通常支持下列动作:</p>
<ul>
  <li>设置和移除行中的断点 - 遇到 <a href="http://en.wikipedia.org/wiki/Breakpoint">断点</a> 时暂停执行.</li>
  <li>单步调试代码 - 逐语句, 逐过程或跳出函数和子程序.</li>
  <li>检查所有变量或特殊变量.</li>
  <li>查看正在运行的子程序和函数的堆栈.</li>
</ul>
<p>注意此功能对于已编译脚本中是无法使用的.</p>
<p>要启用交互调试, 首先要运行一个受支持的调试器客户端然后使用命令行开关 <b>/Debug</b> 运行脚本.</p>
<pre class="Syntax">AutoHotkey.exe /Debug[=<i>SERVER</i>:<i>PORT</i>] ...</pre>
<p><i>SERVER</i> 和 <i>PORT</i> 可以省略. 例如, 下面两个是等同的:</p>
<pre>AutoHotkey /Debug "myscript.ahk"
AutoHotkey /Debug=localhost:9000 "myscript.ahk"</pre>
<p id="debug_attach"><span class="ver">[AHK_L 59+]:</span> 要向已经在运行的脚本附加调试器, 向脚本发送消息, 如下所示:</p>
<pre>ScriptPath = <em>; SET THIS TO THE FULL PATH OF THE SCRIPT</em>
DetectHiddenWindows On
ifWinExist %ScriptPath% ahk_class AutoHotkey
    <em>; 可选参数:
    ;   wParam  = the IPv4 address of the debugger client, as a 32-bit integer.
    ;   lParam  = the port which the debugger client is listening on.</em>
    PostMessage DllCall("RegisterWindowMessage", "str", "AHK_ATTACH_DEBUGGER")
</pre>
<p>一旦调试器连接后, 可以通过发送 "detach" DBGp 命令在不终止脚本的情况下分离调试器.</p>

<h2 id="port">AutoHotkey.exe 的可移植性</h2>
<p>运行任何 .ahk 脚本只需要 AutoHotkey.exe 这一个文件. 唯一的例外是 Windows NT4, 在此系统上运行任何使用 <a href="commands/Process.htm">Process command</a> 的脚本需要一个 psapi.dll 的副本 (存在于 AutoHotkey 文件夹).</p>
<p><span class="ver">[AHK_L 51+]:</span> 重命名 AutoHotkey.exe 文件会同时改变 <a href="#defaultfile">默认情况下</a> 它运行的脚本, 这是在没有安装 AutoHotkey 的计算机上运行脚本的一种可选方法. 例如, 没有指定文件名执行 <i>MyScript</i>.exe 会自动运行 <i>MyScript</i>.ahk, 但也能运行其他脚本.</p>
<h2 id="install">安装程序选项</h2>
<p>要静默安装 AutoHotkey 到默认目录 (这与手动安装显示的目录相同), 向安装程序传递 /S 参数 (/S 必须是大写的). 例如:</p>
<pre>AutoHotkey104307_Install.exe /S</pre>
<p>可以参数 /D 指定默认目录外的其他目录作为安装目录 (未使用 /S 参数时, 这样可以改变显示在安装程序中的默认目录). 例如:</p>
<pre>AutoHotkey104307_Install.exe /S /D=C:\Program Files\AutoHotkey</pre>
<p>要静默卸载 AutoHotkey, 向卸载程序传递 /S 参数. 例如:</p>
<pre>&quot;C:\Program Files\AutoHotkey\uninst.exe&quot; /S</pre>
<h2>脚本展示</h2>
<p>参见 <a href="scripts/">这个页面</a> 了解一些有用的脚本.</p>
</body>
</html>
